package com.yeskery.nut.view.beetl;

import com.yeskery.nut.core.MediaType;
import com.yeskery.nut.core.NutException;
import com.yeskery.nut.core.Request;
import com.yeskery.nut.core.Response;
import com.yeskery.nut.view.BaseWebRender;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;

import java.io.ByteArrayOutputStream;
import java.util.Map;

/**
 * Beetl的web渲染器
 * @author sprout
 * @version 1.0
 * 2022-07-02 15:46
 */
public class BeetlWebRender extends BaseWebRender {

    /** 模板对象 */
    private final GroupTemplate groupTemplate;

    /**
     * 构建Beetl的web渲染器
     * @param groupTemplate 模板对象
     * @param mediaType 媒体类型
     */
    public BeetlWebRender(GroupTemplate groupTemplate, MediaType mediaType){
        super(mediaType);
        this.groupTemplate = groupTemplate;
    }

    /**
     * 构建Beetl的web渲染器
     * @param groupTemplate 模板对象
     * @param mediaType 媒体类型
     * @param extendAttributes 扩展属性
     */
    public BeetlWebRender(GroupTemplate groupTemplate, MediaType mediaType, Map<String, ?> extendAttributes){
        super(mediaType);
        super.extendAttributes = extendAttributes;
        this.groupTemplate = groupTemplate;
    }

    /**
     * @param key 模板资源id
     * @param request 请求对象
     * @param response 响应对象
     */
    @Override
    public void render(String key, Request request, Response response) {
        try {
            Template template = groupTemplate.getTemplate(key);
            Map<String, Object> attrs = request.getAttributes();
            for (Map.Entry<String, Object> entry : attrs.entrySet()) {
                template.binding(entry.getKey(), entry.getValue());
            }

            if (extendAttributes != null) {
                template.binding(extendAttributes);
            }

            template.binding("session", request.getSession());
            template.binding("request", request);
            template.binding("serverContext", request.getServerContext());
            template.binding("contextPath", getContextPath());

            if (groupTemplate.getConf().isDirectByteOutput()) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                template.renderTo(baos);
                response.write(baos.toByteArray());
            } else {
                response.write(template.render(), mediaType);
            }

        } catch (Exception e) {
            throw new NutException("Beetl Render Failure.", e);
        }
    }
}
